package com.blog.zip.controller.admin;


import com.auth0.jwt.interfaces.DecodedJWT;
import com.blog.zip.bean.Article;
import com.blog.zip.bean.RespBean;
import com.blog.zip.bean.Tags;
import com.blog.zip.mapper.ArticleMapper;
import com.blog.zip.service.ArticleService;
import com.blog.zip.util.CopyUtil;
import com.blog.zip.util.DateUtil;
import com.blog.zip.util.Markdowns;
import com.blog.zip.util.TokenUtil;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

//@CrossOrigin
@Slf4j
@RestController
public class AdminArticleController {
    private static final String ACCESS_KEY = "-Me0y3v6zAGgXQz8WvWygNO_dCOVI3EK99jCxcYv";
    private static final String SECRET_KEY = "cFbFOwHtGsTWWasNqJO5nxdwiIIAGZV7_dIoCu8-";
    private static final String BUCKET = "zipblog";
    private static final String CDN_HOST = "https://cdn.zipblog.top/";
    @Autowired(required = false)
    private ArticleMapper articleMapper;

    @Autowired
    private ArticleService articleService;

    /**
     * 首页文章分页获取，文章的总数量，文章的总浏览量，标签的总量
     * @desc 这块看似获取文章的接口，实则是获取首页相关数据的接口，包含文章首页内容，文章总浏览量，总数，等等
     */
    @GetMapping("/admin/article/get")
    public Map<String, Object> getArticle(Integer pageNo, Integer pageSize, Integer cmd, HttpServletRequest request) {
        if (pageNo == null) pageNo = 1;
        if (pageSize == null) pageSize = 10;
        int offset = 0;
        offset = (pageNo - 1) * pageSize;
        // 置顶文章
        List<Map<String, Object>> articlePutTop = new ArrayList<>();
        articlePutTop = articleMapper.getAdminArticle(offset, pageSize, 1);
        // 非置顶文章
        List<Map<String, Object>> list = new ArrayList<>();
        int offset2 = offset;
        if (pageNo > 1) {
            List<Map<String, Object>> temp = articleMapper.getArticleTop("admin");

            offset2 = offset - temp.size();
        }

        list = articleMapper.getAdminArticle(offset2 , pageSize - articlePutTop.size(), 0);
        articlePutTop.addAll(list);


        // 文章总篇数
        Integer total = articleMapper.getArticleTotalV3();
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("data", articlePutTop);
        map.put("total", total);
        //找到每一篇文章对应的分类 连表查询
        return map;
    }

    @GetMapping("/admin/sign/preference")
    public Map<String, Object> getArticleSign() {
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> list = articleMapper.getArticlePreference();
        Map<String, Object> data = new HashMap<>();
        for (Map<String, Object> m : list) {
            data.put((String) m.get("oId"), m.get("optionValue"));
        }
        map.put("code", 200);
        map.put("data", data);
        return map;
    }

    /**
     * 管理端：文章的添加逻辑
     *
     * @param article
     * @return
     * @throws ParseException
     */
    @PostMapping("/admin/article/insert")
    public Map addArticle(@RequestBody Map article, HttpServletRequest request) throws ParseException {
        //System.out.println(map);
        Map<String, Object> mapData = new HashMap<>();

        if (article.get("title") == null) {
            mapData.put("msg", "add fail, title is empty");
            mapData.put("errCode", "301");
            return mapData;
        }
        if (article.get("body") == null) {
            mapData.put("msg", "add fail, content is empty");
            mapData.put("errCode", "302");
            return mapData;
        }
        if (article.get("tags") == null) {
            mapData.put("msg", "add fail, tags is empty");
            mapData.put("errCode", "303");
            return mapData;
        }
        String token = request.getHeader("B-Token");
        DecodedJWT verify = TokenUtil.verify(token);
        String id = verify.getClaim("id").asString();
        // 生成时间戳

		        String password= (String) article.get("viewPwd");
// 将字符串转为字节数组
        byte[] passwordBytes = password.getBytes();


        long time = System.currentTimeMillis();
        article.put("id", time);
        article.put("abstractText", article.get("abstract"));
        article.put("authorId", id);
        article.put("content", article.get("body"));
        article.put("imageUrl", article.get("articleImg1URL"));
        article.put("putTop", 0);
        article.put("created", time);
        article.put("updated", time);
        article.put("randomDouble", Math.random());
        article.put("pwd", !password.equals("") ? DigestUtils.md5DigestAsHex(passwordBytes) : "");
        formatParams(article, mapData);


//        // 插入新增文章对应的标签
        String s = (String) article.get("tags");
        List list = Arrays.asList(s.split(","));
        for (Object o : list) {
            long oId = System.currentTimeMillis();
            Map<String, Object> tmp = new HashMap<>();
            long tagId = articleMapper.getTagId(o.toString().trim());
            tmp.put("id", oId);
            tmp.put("articleId", time);
            tmp.put("tagId", tagId);
            articleMapper.addArticleTag(tmp);
        }

//        articleMapper.addArticleToSolo(article);


        // 使用mysql中的触发器，在插入文章之前操作
        articleService.addArticleToSolo(article);



        mapData.put("msg", "add success");
        return mapData;
    }

    @PostMapping("/admin/article/del")
    public RespBean delArticle(@RequestParam("zid") String id) {
        articleMapper.delSoloArticle(id);
        return new RespBean(200, "del success");
    }

    /**
     * 管理端文章的更新 密码使用md5加密
     * @param article
     * @return
     * @throws ParseException
     */
    @PostMapping("/admin/article/update")
    public Map editArticle(@RequestBody Map article) throws ParseException {
        Map<String, Object> mapData = new HashMap<>();
        if (article.get("title") == null) {
            mapData.put("msg", "add fail, title is empty");
            mapData.put("errCode", "301");
            return mapData;
        }
        if (article.get("body") == null) {
            mapData.put("msg", "add fail, content is empty");
            mapData.put("errCode", "302");
            return mapData;
        }
        if (article.get("tags") == null) {
            mapData.put("msg", "add fail, tags is empty");
            mapData.put("errCode", "303");
            return mapData;
        }
        // 生成时间戳
        // title abstract body imageUrl updated sign pwd permalink
        long time = Calendar.getInstance().getTimeInMillis();;
        log.info("{}",time);

//        DigestUtils.md5DigestAsHex((byte[]) article.get("viewPwd"));

        String password= (String) article.get("viewPwd");
// 将字符串转为字节数组
        byte[] passwordBytes = password.getBytes();

        article.put("abstractText", article.get("abstract"));
        article.put("content", article.get("body"));
        article.put("imageUrl", article.get("articleImg1URL"));
        article.put("updated", time);
        article.put("pwd", !password.equals("") ? DigestUtils.md5DigestAsHex(passwordBytes) : "");
        formatParams(article, mapData);


        //b3_tags_article 中插入文章对应的标签

        // 更新之前删除，删除之前所有的文章与标签的关联操作 重新建立关系
        articleMapper.deleteArticleTag((String) article.get("id"));

        String s = (String) article.get("tags");
        List list = Arrays.asList(s.split(","));
        for (Object o : list) {
            long oId = System.currentTimeMillis();
            Map<String, Object> tmp = new HashMap<>();
            long tagId = articleMapper.getTagId(o.toString().trim());
            tmp.put("id", oId);
            tmp.put("articleId", article.get("id"));
            tmp.put("tagId", tagId);
            articleMapper.addArticleTag(tmp);
        }


        articleService.updateSoloArticle(article);


        mapData.put("msg", "update success");
        return mapData;
    }

    private void formatParams(@RequestBody Map article, Map<String, Object> mapData) {
        article.put("signId", article.get("sign"));
        if (article.get("permalink") == null) {
            article.put("permalink", "/article-detail/" + article.get("id"));
        } else {
            article.put("permalink", article.get("permalink"));
        }
        mapData.put("code", 200);
    }

    /**
     * 文章详情的获取
     *
     * @param m
     * @return
     */
    @PostMapping("/admin/article/getById")
    public Map<String, Object> getArticleById(@RequestBody Map<String, Object> m, HttpServletRequest request) throws Exception {
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> article, articleCopy;
        // 当cmd = 1时 管理端获取文章
        Integer cmd = (Integer) m.get("cmd");

        articleCopy = articleService.getArticleByIdV3((String) m.get("id"),cmd);
        article = CopyUtil.deepClone(articleCopy);
        if (article == null) {
            Map res = new HashMap();
            res.put("ret", -1);
            res.put("msg", "article is delete");
            return res;
        }
        map.put("data", article);
        map.put("code", 200);
        return map;
    }
}

